using System;
using System.Collections;
using System.Data;
using System.Threading;
using System.Web.UI;
using System.Web.UI.WebControls;
using PHSRAG.Insight21.Agreements;
using PHSRAG.Insight21.Common.Pages;
using PHSRAG.Insight21.Context;
using PHSRAG.Insight21.InsightWebControls;
using PHSRAG.Insight21.Policy;
using PHSRAG.Insight21.SearchContext;
using PHSRAG.Security.Enumerations;
using PHSRAG.Utility;
using PHSRAG.Security;
using System.Xml;
using System.IO;
using System.Text;
using PHSRAG.WebControls;
using Constants = PHSRAG.Insight21.InsightUtilities.Constants;
using Helper = PHSRAG.WebControls.Helper;

namespace PHSRAG.Insight21.Agreements
{
    /// <summary>
    /// The StimulusReporting object is the class supporting the like-named page. It displays a report view of all
    /// the 3 major components required to submit to the federal government in every quarter of the year.
    /// </summary>    
    public partial class AdvanceFundRequestLanding : NoCachePage
    {
        #region Instance Variables (Private)
                
        private ICachePolicy cachePolicy;
        private ICachePolicy pageCachePolicy;
        
        private int loggedInUserID;  
        private int intAccessLevel;
        private DataTable dtGrid;

        #endregion

        #region Enums (Private)

        private enum FundRequestTableColumnIndex
        {
            DateSubmitted,
            SubmittedBy,
            DateLastUpdate,
            DaysToComplete,
            PI,
            Sponsor,
            Hospital,
            COS,
            RequestStatus,
            Action,
            CreatedBy
        }

        #endregion

        #region Constants

        private const string PageCacheKey = "pageCacheKey_3FA3B81F-B3B0-4c74-9F2A-3DF7FD7B0DC8";
        private const string CurrentPageIndexKey = "AdvanceFundRequestLandingPageIndexKey_119B5DD3-0ED1-45f0-B455-6F9C0473E580";
        private const string SortKey = "AdvanceFundRequestLandingSortKey_27F443FA-B77C-4ced-81B0-2099CD9A586E";
        private const string SortDirection = "AdvanceFundRequestLandingSortDirection_B6836CCD-FA0B-4690-A0FC-52352E590F6C";
        private const string PropNum = "AdvanceFundRequestLandingPropNum_B6836CCD-FA0B-4690-A0FC-52352E590F6C";
        private const string PageName = "Advance Fund Request Landing";

        #endregion

        #region Private Properties

        /// <summary>
        /// Get/Set the current page within the datagrid for display. This information persists across page loads.
        /// </summary>
        private int CurrentPageIndex
        {
            get
            {
                Hashtable h = pageCachePolicy.GetCachedObject(Keys.AdvanceFundRequestLandingPageKey) as Hashtable;
                return (h == null || h[CurrentPageIndexKey] == null) ? 0 : (int)h[CurrentPageIndexKey];
            }
            set
            {
                Hashtable h = pageCachePolicy.GetCachedObject(Keys.AdvanceFundRequestLandingPageKey) as Hashtable ?? new Hashtable();
                h[CurrentPageIndexKey] = value;

                pageCachePolicy.Cache(Keys.AdvanceFundRequestLandingPageKey, h);
            }
        }

        /// <summary>
        /// 
        /// </summary>
        private string SortField
        {
            get
            {
                Hashtable h = pageCachePolicy.GetCachedObject(Keys.AdvanceFundRequestLandingPageKey) as Hashtable;
                return (h == null || h[SortKey] == null) ? "" : h[SortKey].ToString();
            }
            set
            {
                Hashtable h = pageCachePolicy.GetCachedObject(Keys.AdvanceFundRequestLandingPageKey) as Hashtable ?? new Hashtable();
                h[SortKey] = value;

                pageCachePolicy.Cache(Keys.AdvanceFundRequestLandingPageKey, h);
            }
        }

        private string SortDir
        {
            get
            {
                Hashtable h = pageCachePolicy.GetCachedObject(Keys.AdvanceFundRequestLandingPageKey) as Hashtable;
                return (h == null || h[SortDirection] == null) ? "" : h[SortDirection].ToString();
            }
            set
            {
                Hashtable h = pageCachePolicy.GetCachedObject(Keys.AdvanceFundRequestLandingPageKey) as Hashtable ?? new Hashtable();
                h[SortDirection] = value;

                pageCachePolicy.Cache(Keys.AdvanceFundRequestLandingPageKey, h);
            }
        }

        private string ProposalNumber
        {
            get
            {
                Hashtable h = pageCachePolicy.GetCachedObject(Keys.AdvanceFundRequestLandingPageKey) as Hashtable;
                return (h == null || h[PropNum] == null) ? "" : h[PropNum].ToString();
            }
            set
            {
                Hashtable h = pageCachePolicy.GetCachedObject(Keys.AdvanceFundRequestLandingPageKey) as Hashtable ?? new Hashtable();
                h[PropNum] = value;

                pageCachePolicy.Cache(Keys.AdvanceFundRequestLandingPageKey, h);
            }
        }

        #endregion

        #region Event Handlers

        /// <summary>
        /// Handler for the event raised when the FirstPage link in clicked in the Pager control.
        /// Set the current page index to 0, bind the datagrid with data and manage navigation links. To avoid superfluous
        /// data binding activites, no action is taken if the current page index is already 0.
        /// </summary>
        /// <param name="sender">Control which rasied the event</param>
        /// <param name="e">Arguments associated with the event</param>
        protected void OnFirstPage(object sender, CommandEventArgs e)
        {
            try
            {
                CurrentPageIndex = 0;
                LoadDataGrid();                
            }
            catch (Exception ex)
            {
                DisplayExceptionReport(ex);
            }
        }
        
        /// <summary>
        /// Handler for the event raised when the LastPage link in clicked in the Pager control.
        /// Set the current page index to one less than the total page count (index is 0-based), bind the datagrid with
        /// data and manage navigation links. To avoid superfluous data binding activites, no action is taken if the current
        /// page index is already corresponding to the last page.
        /// </summary>
        /// <param name="sender">Control which rasied the event</param>
        /// <param name="e">Arguments associated with the event</param>
        protected void OnLastPage(object sender, CommandEventArgs e)
        {
            try
            {
                CurrentPageIndex = pagerAboveDatagrid.PageCount - 1;
                LoadDataGrid();
            }
            catch (Exception ex)
            {
                DisplayExceptionReport(ex);
            }
        }

        /// <summary>
        /// Handler for the event raised when the NextPage link in clicked in the Pager control.
        /// Increment the current page index, bind the datagrid with data and manage navigation links.
        /// </summary>
        /// <param name="sender">Control which rasied the event</param>
        /// <param name="e">Arguments associated with the event</param>
        protected void OnNextPage(object sender, CommandEventArgs e)
        {
            try
            {
                ++CurrentPageIndex;
                LoadDataGrid();
            }
            catch (Exception ex)
            {
                DisplayExceptionReport(ex);
            }
        }

        /// <summary>
        /// Handler for the event raised when the PreviousPage link in clicked in the Pager control.
        /// Decrement the current page index, bind the datagrid with data and manage navigation links.
        /// </summary>
        /// <param name="sender">Control which rasied the event</param>
        /// <param name="e">Arguments associated with the event</param>
        protected void OnPreviousPage(object sender, CommandEventArgs e)
        {
            try
            {
                --CurrentPageIndex;
                LoadDataGrid();
            }
            catch (Exception ex)
            {
                DisplayExceptionReport(ex);
            }
        }

        /// <summary>
        /// Handler for the event raised when the page is being loaded.
        /// Initialize the bread crumb control, set the page size for the data grid, and load the data grid with data.
        /// If on the first page within the data grid, initalize the pager control. Notice that even when in the context
        /// of a non-postback load, the current page index may not be 0 since the page index is restored from the cache.
        /// The data grid is loaded with data on every page load because the data grid is set not to use ViewState.
        /// </summary>
        /// <param name="sender">Control which rasied the event</param>
        /// <param name="e">Arguments associated with the event</param>
        protected void Page_Load(object sender, EventArgs e)  
        {
            try
            {
                annunciator.Message = string.Empty;
                breadCrumb.Add("Advance Fund Request", Settings.GetKeyValue("SubNavigation.Agreements.AdvanceFundRequestLandingURL", ""), 1);

                pageName.Text = PageName;
                downloadBar.SQLReportName = "AdvanceFundRequest_Landing";
                                
                loggedInUserID = ((UserContext)cachePolicy.GetCachedObject(UserContext.CacheKey)).DomainUserId;
                downloadBar.SQLReportName = "advancefundrequest";

                if (!IsPostBack)
                {
                    if ((int)Security.Enumerations.ModuleRoleBit.SetArraIsFinalReport > 0)
                    intAccessLevel = intAccessLevel | ((UserContext)cachePolicy.GetCachedObject(UserContext.CacheKey)).ModuleRoleBitmask;

                    CurrentPageIndex = 0;
                    SortField = "Afr.DateSubmitted";
                    SortDir = PHSRAG.Insight21.InsightUtilities.Constants.SortViewDescending;
                    LoadDataGrid();     
                }
            }
            catch (Exception ex)
            {
                annunciator.Title = "Following error(s) occurred during PageLoad:";
                annunciator.Message = ExceptionReport.GetExceptionInfo(ex, false);
            }
            finally
            {
                agreementsSubNavigation.SelectedLink = "Advance Fund Request";
            }
        }

        /// <summary>
        /// Purges the cache and sets the correct search context level before the breadcrumb performs a redirect.
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        protected void OnNavigate(object sender, CommandEventArgs e)
        {
            if (((CommandEventArgs)(e.CommandArgument)).CommandName == Convert.ToString((int)SearchCriteria.Level.Summary))
            {
                //set the search context's level to the correct level
                CommonSearchContext searchContext = (CommonSearchContext)cachePolicy.GetCachedObject(CommonSearchContext.CacheKey);
                searchContext.CurrentLevel = SearchCriteria.Level.Summary;
            }
            PurgeCache();
        }

        /// <summary>
        /// Invoked by the download bar when it catches an exception.
        /// </summary>
        /// <param name="sender">Control which raised the event</param>
        /// <param name="e">Argument associated with the event</param>
        protected void OnDownloadFailed(object sender, CommandEventArgs e)
        {
            annunciator.Title = "Following error(s) occurred while downloading";
            annunciator.Message = ExceptionReport.GetExceptionInfo((Exception)e.CommandArgument, false);
        }

        /// <summary>
        /// Purge the cached BO from the cache and remove its key from the cache.
        /// </summary>
        private void PurgeCache()
        {
            System.Diagnostics.Trace.WriteLine("Purging Advance Fund Request...");
            ResultsCache.PurgeObject(cachePolicy);
        }

        /// <summary>
        /// Purges the cache before the agreements subnavigation header performs a redirect.
        /// </summary>
        /// <param name="sender">Control which rasied the event.</param>
        /// <param name="e">Arguments associated with the event.</param>
        protected void OnSubNavigate(object sender, CommandEventArgs e)
        {
            PurgeCache();
        }

        /// <summary>
        /// Resets the Agreements subnavigation selected link before the 
        /// header performs a redirect.
        /// </summary>
        /// <param name="sender">Control which rasied the event.</param>
        /// <param name="e">Arguments associated with the event.</param>
        protected void OnHeaderNavigate(object sender, CommandEventArgs e)
        {
            PurgeCache();
            agreementsSubNavigation.Reset();
        }

        #endregion

        #region Private Methods

        /// <summary>
        /// Method to retrieve the list of Fund Request based on the userId.
        /// </summary>
        /// <returns>ProposalData DataSet</returns>
        private DataTable GetAdvanceFundRequest(int StartPageIndex, int EndingPageIndex, int PageSize, string SortOrder)
        {
            AdvanceFundRequest ar = new AdvanceFundRequest();
            try
            {
                dtGrid = ar.GetAdvanceFundRequest(DataAccess.GetConnectionString(), StartPageIndex, EndingPageIndex, PageSize, SortOrder, loggedInUserID);
            }
            catch (Exception e)
            {
                throw new Exception(e.Message, e.InnerException);
            }
            return dtGrid;            
        }

        /// <summary>
        /// Method to delete a fund request from the list.
        /// </summary>
        /// <param name="PropNumber">Proposal Number</param>
        private void DeleteFundRequest(string PropNumber)
        {
            AdvanceFundRequest ar = new AdvanceFundRequest();
            try
            {
                ar.DeleteFundRequest(DataAccess.GetConnectionString(), PropNumber, loggedInUserID);
            }
            catch (Exception e)
            {
                throw new Exception(e.Message, e.InnerException);
            }
        }

        /// <summary>
        /// Load the datagrid with sufficient data for display within one page of the data grid. This is done as follows:
        /// Get the summaries for all agreements that the user has access to. Use that to initialize the data grid and
        /// the pager controls based on the page size of the data grid.
        /// The pagers are made visible only when more than one page of data can be displayed.
        /// If there is no data to display, warn the user via the annunciator.
        /// </summary>
        private void LoadDataGrid()
        {
            try
            {
                DataTable dt = new DataTable();
                int intStartPageIndex = CurrentPageIndex;
                int intEndingPageIndex = CurrentPageIndex + 1;
                int intPageSize = gvPIQuestionnaires.PageSize;
                string strSort = SortField + " " + SortDir;

                dt = GetAdvanceFundRequest(intStartPageIndex, intEndingPageIndex, intPageSize, strSort);
                                               
                pagerBelowDatagrid.RecordCount = pagerAboveDatagrid.RecordCount = (dt.Rows.Count > 0 ? Convert.ToInt32(dt.Rows[0]["RecordCount"].ToString()) : 0);
                int currentPageIndex = CurrentPageIndex;
                int pageCount = (pagerAboveDatagrid.RecordCount / gvPIQuestionnaires.PageSize) +
                    (((pagerAboveDatagrid.RecordCount % gvPIQuestionnaires.PageSize) == 0) ? 0 : 1);
                pagerBelowDatagrid.PageCount = pagerAboveDatagrid.PageCount = pageCount;
                pagerBelowDatagrid.CurrentPage = pagerAboveDatagrid.CurrentPage = currentPageIndex + 1;

                gvPIQuestionnaires.DataSource = dt;
                gvPIQuestionnaires.DataBind();

                if (dt.Rows.Count < 1)
                {
                    downloadBar.Visible = false;
                    gvPIQuestionnaires.Visible = false;
                    pagerAboveDatagrid.Visible = false;
                    pagerBelowDatagrid.Visible = false;
                    annunciator.Message = "No data found for Advance Fund Request.";
                }
                else
                {
                    downloadBar.Visible = true;
                    gvPIQuestionnaires.Visible = true;
                    pagerAboveDatagrid.Visible = true;
                    pagerBelowDatagrid.Visible = true;
                    int startIndex = currentPageIndex * gvPIQuestionnaires.PageSize;
                    pagerBelowDatagrid.FirstRecord = pagerAboveDatagrid.FirstRecord = startIndex + 1;
                    pagerBelowDatagrid.LastRecord = pagerAboveDatagrid.LastRecord = ((startIndex + gvPIQuestionnaires.PageSize) > pagerBelowDatagrid.RecordCount ? pagerBelowDatagrid.RecordCount : startIndex + gvPIQuestionnaires.PageSize);
                }
            }
            catch (Exception ex)
            {
                pagerBelowDatagrid.Visible = pagerAboveDatagrid.Visible = false;
                annunciator.Message = ExceptionReport.GetExceptionInfo(ex, false);
            }
        }
        
        #endregion

        #region DisplayExceptionReport
        /// <summary>
        /// Displays an error message on the screen to the user with the exception, and all
        /// inner exception messages.
        /// </summary>
        /// <param name="ex">The exception to report on</param>
        private void DisplayExceptionReport(Exception ex)
        {
            annunciator.Title = PHSRAG.Insight21.InsightUtilities.Constants.Annunciator.Title;
            annunciator.Message = ExceptionReport.GetExceptionInfo(ex, false);
        }

        #endregion DisplayExceptionReport

        #region Web Form Designer generated code

        /// <summary>
        /// Handler for the event raised when the page is being initialized.
        /// Retrieve the cache policy in force. Deposit event handlers to support the datagrid pagination.
        /// </summary>
        /// <param name="e">Argument associated with the event</param>
        protected override void OnInit(EventArgs e)
        {
            InitializeComponent();
            base.OnInit(e);

            cachePolicy = (Policy.ICachePolicy)Session[Policy.Names.CachePolicyKey];
            pageCachePolicy = (Policy.ICachePolicy)Session[Policy.Names.PageCachePolicyKey];
        }

        /// <summary>
        /// Required method for Designer support - do not modify
        /// the contents of this method with the code editor.
        /// </summary>
        private void InitializeComponent()
        {
        }

        #endregion
       
        protected void imgBtnRequestAdvance_Click(object sender, ImageClickEventArgs e)
        {
            // opening a fresh request page
            ProposalNumber = "0";
            Response.Redirect("AdvanceFundRequestForm.aspx", false);
        }

        protected void gvPIQuestionnaires_OnSorting(object sender, GridViewSortEventArgs e)
        {
            try
            {
                if (e.SortExpression != string.Empty)
                {
                    CurrentPageIndex = 0;

                    if (e.SortExpression == SortField)
                        SortDir = (PHSRAG.Insight21.InsightUtilities.Constants.SortViewAscending == SortDir) ? PHSRAG.Insight21.InsightUtilities.Constants.SortViewDescending : PHSRAG.Insight21.InsightUtilities.Constants.SortViewAscending;
                    else
                        SortDir = PHSRAG.Insight21.InsightUtilities.Constants.SortViewAscending;

                    SortField = e.SortExpression;
                    LoadDataGrid();
                }
            }
            catch (Exception ex)
            {
                DisplayExceptionReport(ex);
            }
        }

        protected void gvPIQuestionnaires_RowDataBound(object sender, GridViewRowEventArgs e)
        {
            if (e.Row.RowType == DataControlRowType.DataRow)
            {
                ImageButton lnkAction = e.Row.FindControl("ibDelete") as ImageButton;
                if (e.Row.Cells[(int)FundRequestTableColumnIndex.RequestStatus].Text.ToString().ToLower() == "draft")
                {
                    Label lblBy = e.Row.FindControl("CreatedBy") as Label;
                    if (lblBy.Text.Trim() == loggedInUserID.ToString().Trim())
                    {
                        lnkAction.ImageUrl = "../Images/b_delete.gif";
                        lnkAction.Enabled = true;
                        lnkAction.Attributes.Add("onclick", "return confirmdelete();");
                        lnkAction.ToolTip = "delete request";
                    }
                    else
                    {
                        lnkAction.Visible = false;
                    }
                }
                else
                {
                    lnkAction.Visible = false;
                }
            }
        }

        protected void gvPIQuestionnaires_OnRowCreated(object sender, GridViewRowEventArgs e)
        {
            try
            {
                if (e.Row.RowType == DataControlRowType.Header)
                {
                    Image imgSortOrder = new Image();
                    foreach (TableCell tc in e.Row.Cells)
                    {
                        if (tc.HasControls())
                        {
                            LinkButton lbLinkButton = (LinkButton)tc.Controls[0];
                            if (SortField == lbLinkButton.CommandArgument)
                            {
                                if (SortDir == PHSRAG.Insight21.InsightUtilities.Constants.SortViewAscending)
                                    imgSortOrder.ImageUrl = "../Images/arrowUp.gif";
                                else
                                    imgSortOrder.ImageUrl = "../Images/arrowDown.gif";
                                tc.VerticalAlign = VerticalAlign.Bottom;
                                tc.Controls.Add(imgSortOrder);
                            }
                        }
                    }
                }
            }
            catch (Exception ex)
            {
                DisplayExceptionReport(ex);
            }
        }

        protected void gvPIQuestionnaires_RowCommand(object sender, GridViewCommandEventArgs e)
        {
            try
            {
                ProposalNumber = e.CommandArgument.ToString().Trim();
                if (e.CommandName.ToLower() == "deleteprop")
                {
                    DeleteFundRequest(ProposalNumber);
                    LoadDataGrid();
                }
                else if (e.CommandName.ToLower() == "view")
                {
                    ImageButton iBut = (ImageButton)e.CommandSource;
                    string[] ImgUrl = iBut.ImageUrl.ToString().Split('/');
                    if (ImgUrl[ImgUrl.Length - 1] == "b_edit.gif")
                    {
                        Response.Redirect("AdvanceFundRequestForm.aspx", false);
                    }
                    else 
                    {
                        Response.Redirect("AdvanceFundRequestReview.aspx", false);
                    }
                }
            }
            catch (Exception ex)
            {
                DisplayExceptionReport(ex);
            }            
        }
    }
}